using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Framework.DataTable
{
    public class FieldInfo
    {
        public string Name;
        public SimpleTypeDef Type;
        public string Define;
        //代码声明索引
        public int DeclarIndex;
        //注释说明
        public string Comment;
        //数据分支名列表
        public List<string> Branch = new List<string>();
        //数据分支索引列表
        public List<int> DataIndex = new List<int>();
        public FieldInfo()
        {
            Branch = new List<string>();
            DataIndex = new List<int>();
        }
        public bool HasDefine(string value)
        {
            if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(Define)) return true;
            return Define.Contains(value);
        }
        public int GetBranchIndex(string branch)
        {
            if (Branch.Count <= 1) return DataIndex[0];
            var id = Branch.IndexOf(branch);
            if (id >= 0)
            {
                return DataIndex[id];
            }
            return -1;
        }
        public FieldInfo Clone()
        {
            var f = new FieldInfo();
            f.Name = Name;
            f.Type = Type;
            f.Define = Define;
            f.DeclarIndex = DeclarIndex;
            f.Comment = Comment;
            f.Branch = Branch;
            f.DataIndex = DataIndex;
            return f;

        }
    }
    public class DataTableFieldHeader
    {
        private static readonly Regex FieldNameRegex = new Regex(@"^[A-Z][A-Za-z0-9_]*$");
        private static readonly Regex nameRegex = new Regex(@"^[A-Za-z][A-Za-z0-9_]*$");
        public string Name;
        public bool NeedCompile;
        public List<FieldInfo> FieldInfos { get; private set; }
        public List<string> DataBranchs { get; private set; }
        public List<string> Defines { get; private set; }
        public FieldInfo IndexField { get; private set; }
        private Dictionary<string, FieldInfo> _fields;
        public DataTableFieldHeader()
        {
            FieldInfos = new List<FieldInfo>();
            _fields = new Dictionary<string, FieldInfo>();
            DataBranchs = new List<string>();
            Defines = new List<string>();
            IndexField = null;
        }
        public int GetHeaderVersion()
        {
            if (FieldInfos == null) return -1;
            StringBuilder builder = new StringBuilder();
            foreach (var item in FieldInfos)
            {
                builder.Append(item.Name);
                builder.Append(item.Type.GetInfo());
                var len = item.Branch.Count;
                for (var i = 0; i < len; i++)
                {
                    builder.Append(item.Branch[i]);
                    builder.Append(item.DataIndex[i]);
                }
            }
            return builder.ToString().GetHashCode();
        }
        public bool ContainsDefine(string value)
        {
            foreach (var item in Defines)
            {
                if (item.Contains(value))
                {
                    return true;
                }
            }
            return false;
        }
        public int GetDefineCount(string value)
        {
            int count = 0;
            foreach (var item in FieldInfos)
            {
                if (item.HasDefine(value))
                {
                    count++;
                }
            }
            return count;
        }
        public bool AddFieldInfo(string name, string type, string define, int dataId, string comment = "")
        {
            if (string.IsNullOrEmpty(name) || name.StartsWith("#"))
            {
                return true;
            }
            if (string.IsNullOrEmpty(type))
            {
                return true;
            }
            var branch = string.Empty;
            var names = name.Split("@".ToCharArray());
            if (names.Length > 1)
            {
                name = Utils.Text.FirstCharUpper(names[0].Replace(" ", ""));
                branch = names[1].Replace(" ", "");
            }
            if (!FieldNameRegex.IsMatch(name))
            {
                FrameworkLog.LogErrorFormat("字段名 {0} 不符合规范", name);
                return false;
            }
            if (!string.IsNullOrEmpty(branch))
            {
                if (!nameRegex.IsMatch(branch))
                {
                    FrameworkLog.LogErrorFormat("数据分支名 {0} 不符合规范", branch);
                    return false;
                }
            }
            if (!_fields.TryGetValue(name, out FieldInfo info))
            {
                info = new FieldInfo();
                info.Name = name;
                info.Define = define;
                info.Comment = comment;
                info.Type = new SimpleTypeDef(type);
                if (info.Type.Name == "index")
                {
                    if (IndexField != null)
                    {
                        FrameworkLog.LogErrorFormat("已经添加了索引 {0} ,不支持多个索引", IndexField.Name);
                        return false;
                    }
                    if (info.Type.TypeName != "int" && info.Type.TypeName != "string")
                    {
                        FrameworkLog.LogErrorFormat("索引类型只支持int和string ,不支持{0}", info.Type.TypeName);
                        return false;
                    }
                    IndexField = info;
                }
                info.DeclarIndex = FieldInfos.Count;
                FieldInfos.Add(info);
                _fields.Add(name, info);
            }
            if (!info.Branch.Contains(branch))
            {
                info.Branch.Add(branch);
                info.DataIndex.Add(dataId);
            }
            return true;
        }
        public void Init()
        {
            foreach (var item in FieldInfos)
            {
                foreach (var b in item.Branch)
                {
                    if (string.IsNullOrEmpty(b)) continue;
                    if (DataBranchs.Contains(b))
                    {
                        continue;
                    }
                    DataBranchs.Add(b);
                }
                if (!string.IsNullOrEmpty(item.Define))
                {
                    var len = item.Define.Length;
                    for (var i = 0; i < len; i++)
                    {
                        var d = item.Define.Substring(i, 1);
                        if (!Defines.Contains(d))
                        {
                            Defines.Add(d);
                        }
                    }
                }
            }
            if (DataBranchs.Count < 1)
            {
                DataBranchs.Add("");
            }
        }

    }
}